﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows;
using RiskMan.Config;
using RiskMan.DataClass;
using RiskMan.DataClass.Models;
using RiskMan.DataClass.Models.Quik;
using RiskMan.Models;
using RiskMan.Properties;
using RiskMan.Views.Dialogs;
using QuikIntegration.dde;
using RiskMan.DataClass.Models.RM;

namespace RiskMan.Views.RiskManager
{
    class RMILogik
    {
        private DataClass.Data data;
        private MainWindow mainWindow;
        private RiskManager riskManager;

        public RMILogik()
        {

        }

        public RMILogik(MainWindow mainWindow, RiskManager riskManager)
        {
            this.mainWindow = mainWindow;
            this.data = mainWindow._dataProvider;
            this.riskManager = riskManager;
        }

        public void Start(RMItemsClass rmRunnedItems)
        {
            IsParam();

            try
            {

                for (int i = 0; i < rmRunnedItems.Count; i++)
                {
                    if (rmRunnedItems[i].AccountLimeteItem == null)
                        rmRunnedItems[i].AccountLimeteItem = new AccountLimiteItem();
                    AccountLimiteItem item = rmRunnedItems[i].AccountLimeteItem;
                    item.Account = rmRunnedItems[i].Account;
                    item.ClientCode = rmRunnedItems[i].ClientCode;


                    // время работы
                    if (new WorkingTimeClass(item.Account).IsWork() == true)
                    {
                        item.Comiss = new AccountLimiteItem().GetComiss(rmRunnedItems[i], data);
                        item.Profit = new AccountLimiteItem().GetProfit(rmRunnedItems[i], data);
                        bool boolCaclTrallingProfitDeal = false; //если расчет по треллинг сделке рассчитывается, то смотрим изменилась ли позиция и если да, то перезаписываем точку отчета

                        if (item.Account == item.ClientCode)
                        {
                            if ((rmRunnedItems[i].ConsiderVMND == true) && (item.GetDohod(rmRunnedItems[i], data) + item.GetVarMarga(rmRunnedItems[i], data) > 0))
                                item.CurrentBalance = GetLimitOpenPos(item) - item.Comiss;
                            else
                                item.CurrentBalance = GetLimitOpenPos(item) + item.GetDohod(rmRunnedItems[i], data) + item.GetVarMarga(rmRunnedItems[i], data) - item.Comiss;


                            item.CumVM = 0;

                            #region Вычисление ВМ в режиме реального времени.

                            for (int j = 0; j < data.FortsPositionsList.Count; j++)
                            {
                                if (data.FortsPositionsList[j].Account == item.Account)
                                {


                                    if (item.InstrumetnsPricOpen != null)
                                    {
                                        if (item.InstrumetnsPricOpen.Count(a => a.Instrument == data.FortsPositionsList[j].Seccode) == 0)
                                        {
                                            if (data.FortsPositionsList[j].CurrentEmptyPos != 0)
                                            {
                                                item.InstrumetnsPricOpen.Add(new InstrumentsAvaragePriceOpen()
                                                {
                                                    Instrument = data.FortsPositionsList[j].Seccode,
                                                    PriceOpen = data.GetLastPrice(data.FortsPositionsList[j].Seccode),
                                                    CumSum = 0,
                                                    Quantity = data.FortsPositionsList[j].CurrentEmptyPos,
                                                    PrevQuantity = data.FortsPositionsList[j].CurrentEmptyPos
                                                });
                                                boolCaclTrallingProfitDeal = true;
                                            }
                                        }

                                        foreach (var itemInstr in item.InstrumetnsPricOpen)
                                        {
                                            if (itemInstr.Instrument == data.FortsPositionsList[j].Seccode)
                                            {



                                                if (data.GetStepPrice(itemInstr.Instrument) >= 1)
                                                {

                                                    if (itemInstr.PrevQuantity >= 0)
                                                        itemInstr.CumSum = itemInstr.CumSum + (data.GetLastPrice(itemInstr.Instrument) - itemInstr.PriceOpen) * itemInstr.Quantity / data.GetStepPrice(itemInstr.Instrument) * data.GetStepPricet(itemInstr.Instrument);

                                                    if (itemInstr.PrevQuantity <= 0)
                                                        itemInstr.CumSum = itemInstr.CumSum + (itemInstr.PriceOpen - data.GetLastPrice(itemInstr.Instrument)) * itemInstr.Quantity / data.GetStepPrice(itemInstr.Instrument) * data.GetStepPricet(itemInstr.Instrument);
                                                    //cfg.SetLog("Last=" + data.GetLastPrice(itemInstr.Instrument) + " Open=" + itemInstr.PriceOpen + " cum=" + itemInstr.CumSum, mainWindow.ListBox_Logs);
                                                }
                                                else
                                                {
                                                    if (itemInstr.PrevQuantity >= 0)
                                                        itemInstr.CumSum = itemInstr.CumSum + (data.GetLastPrice(itemInstr.Instrument) - itemInstr.PriceOpen) * itemInstr.Quantity * data.GetStepPricet(itemInstr.Instrument);

                                                    if (itemInstr.PrevQuantity <= 0)
                                                        itemInstr.CumSum = itemInstr.CumSum + (itemInstr.PriceOpen - data.GetLastPrice(itemInstr.Instrument)) * itemInstr.Quantity * data.GetStepPricet(itemInstr.Instrument);
                                                }

                                                if (itemInstr.Quantity != data.FortsPositionsList[j].CurrentEmptyPos)
                                                    boolCaclTrallingProfitDeal = true;

                                                itemInstr.Quantity = data.FortsPositionsList[j].CurrentEmptyPos;
                                                itemInstr.PrevQuantity = itemInstr.Quantity;
                                                itemInstr.PriceOpen = data.GetLastPrice(itemInstr.Instrument);

                                                //item.CumVM = item.CumVM + itemInstr.CumSum;
                                                item.CumVM = 0;
                                            }
                                        }
                                    }

                                }

                            }



                            //записываем последнее изменение ВМ
                            if (item.LastVM != item.GetVarMarga(rmRunnedItems[i], data))
                            {
                                //cfg.SetLog(item.LastVM.ToString() + "+" + item.CumVM.ToString() + "=" + item.GetVarMarga(rmRunnedItems[i], data).ToString(), mainWindow.ListBox_Logs);
                                item.LastVM = item.GetVarMarga(rmRunnedItems[i], data);
                                item.CumVM = 0;
                                if (item.InstrumetnsPricOpen != null)
                                    item.InstrumetnsPricOpen.Clear();
                                else
                                    item.InstrumetnsPricOpen = new ObservableCollection<InstrumentsAvaragePriceOpen>();

                                for (int j = 0; j < data.FortsPositionsList.Count; j++)
                                {
                                    if (data.FortsPositionsList[j].Account == item.Account)
                                    {
                                        if (data.FortsPositionsList[j].CurrentEmptyPos != 0)
                                        {
                                            item.InstrumetnsPricOpen.Add(new InstrumentsAvaragePriceOpen()
                                            {
                                                Instrument = data.FortsPositionsList[j].Seccode,
                                                PriceOpen = data.GetLastPrice(data.FortsPositionsList[j].Seccode),
                                                CumSum = 0,
                                                Quantity = data.FortsPositionsList[j].CurrentEmptyPos,
                                                PrevQuantity = data.FortsPositionsList[j].CurrentEmptyPos
                                            });
                                        }
                                    }
                                }
                            }
                            #endregion
                        }
                        else
                            item.CurrentBalance = GetLimitOpenPos(item) + item.GetDohod(rmRunnedItems[i], data) - item.Comiss;


                        item.Full = item.Profit + item.CumVM - item.Comiss;

                        if (IsList(item) == false)
                            data.ACLimiteItems.Add(item);
                        GetList(item);
                        item = GetRow(item);



                        //Текущий расчет: Убыток
                        double deposit = this.GetBalance(rmRunnedItems[i]);
                        if (rmRunnedItems[i].TypeEnterLimite == cfg.TypeEnterLimitRmTrallingProfit || (rmRunnedItems[i].TypeEnterLimite == cfg.TypeEnterLimitRmDealTrallingProfit))
                        {
                            if (((deposit + item.CumVM - item.Comiss) >= item.Deposite && rmRunnedItems[i].TypeEnterLimite == cfg.TypeEnterLimitRmTrallingProfit) ||
                                ((deposit + item.CumVM - item.Comiss) >= item.Deposite && rmRunnedItems[i].TypeEnterLimite == cfg.TypeEnterLimitRmDealTrallingProfit &&
                                 boolCaclTrallingProfitDeal))
                                item.Deposite = deposit + item.CumVM - item.Comiss;// + item.Full;



                            item.Full = (deposit - item.Deposite + item.CumVM - item.Comiss);
                        }

                        if (rmRunnedItems[i].TypeEnterLimite == cfg.TypeEnterLimitRmCalcRmBasic)
                            item.Deposite = deposit;

                        if (item.Deposite == 0)
                            item.Full = 0;

                        #region Расчет защиты прибыли

                        if (rmRunnedItems[i].UseDefensePofit)
                        {
                            if (rmRunnedItems[i].PlanProfit <= item.Full)
                            {
                                rmRunnedItems[i].ActiveDefensePofit = true;
                            }
                        }

                        #endregion

                        //Фиксация значения максимальной прибыли
                        if (item.Full > item.MaxBalance)
                            item.MaxBalance = item.Full;

                        item.FullPersent = item.Full / item.Deposite * 100;

                        if (TimeClose(item, rmRunnedItems[i]) == false)
                            return;

                        if (rmRunnedItems[i].TypeCalcutation == cfg.Persent)
                        {
                            if (item.FullPersent <= -rmRunnedItems[i].DrowDown || (item.FullPersent >= rmRunnedItems[i].ProfitBlock && rmRunnedItems[i].ProfitBlock > 0) || rmRunnedItems[i].IsBlock == true ||
                                (rmRunnedItems[i].ActiveDefensePofit == true && rmRunnedItems[i].DecreaseProfit >= item.Full))
                            {
                                CheckCancel(item, rmRunnedItems[i]);
                            }
                        }
                        else
                        {
                            if (item.Full <= -rmRunnedItems[i].DrowDown || (item.Full >= rmRunnedItems[i].ProfitBlock && rmRunnedItems[i].ProfitBlock > 0) || rmRunnedItems[i].IsBlock == true ||
                                (rmRunnedItems[i].ActiveDefensePofit == true && rmRunnedItems[i].DecreaseProfit >= item.Full))
                            {
                                CheckCancel(item, rmRunnedItems[i]);
                            }
                        }




                        this.UpdateList(item);
                    }
                }
            }
            catch
            {

            }
        }
        private bool _continueTime = false;

        /// <summary>
        /// Закрытие позиций перед концом торгов.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="rMItem"></param>
        /// <returns></returns>
        private bool TimeClose(AccountLimiteItem item, RmItem rMItem)
        {
            bool result = true;

            if (_continueTime == false)
            {

                if (item.Account == item.ClientCode)
                {
                    DateTime start = new DateTime();
                    DateTime end = new DateTime();

                    #region initialize timezone

                    if (Settings.Default.IsWorkCPDayCliring == true)
                    {
                        start = Settings.Default.StartDay.Subtract(TimeSpan.FromMinutes(Settings.Default.CPDayCliringValue));
                        end = Settings.Default.StartDay;

                        #region close

                        if (DateTime.Now >= start && DateTime.Now < end)
                        {
                            // закрытие позиций
                            for (int i = 0; i < data.FortsPositionsList.Count; i++)
                            {
                                if (data.FortsPositionsList[i].Account == item.Account)
                                {
                                    if (data.FortsPositionsList[i].CurrentEmptyPos != 0)
                                    {
                                        cfg.SetLog("Риск-менеджер. Счет: " +
                                            item.Account + "-" + item.ClientCode + ": " +
                                            "Фортс. Закрытие позиции перед дневным клирингом" +
                                            //" Блокируемые средства: " + item.Block +
                                            " Средства: " + item.Deposite +
                                            " Текущие средства: " + item.CurrentBalance +
                                            " Операция: " + (data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B') +
                                            " Количество: " + (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos) +
                                            " Цена: " + data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S') +
                                            " Прибыль: " + item.Full +
                                            " Блокировка(Авто): " + rMItem.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                        mainWindow.Terminals.SendOrder
                                        (
                                            data.FortsPositionsList[i].Account,
                                            data.FortsPositionsList[i].Account,
                                            data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B',
                                            data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S'),
                                            (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos),
                                            data.FortsPositionsList[i].Seccode,
                                            data.GetClasscode(data.FortsPositionsList[i].Seccode)
                                        );
                                        result = false;
                                    }
                                }
                            }
                        }

                        #endregion

                    }

                    if (Settings.Default.IsWorkCPNightCliring == true)
                    {
                        start = Settings.Default.StartNight.Subtract(TimeSpan.FromMinutes(Settings.Default.CPNightCliringValue));
                        end = Settings.Default.StartNight;
                        #region close
                        if (DateTime.Now >= start && DateTime.Now < end)
                        {
                            // закрытие позиций
                            for (int i = 0; i < data.FortsPositionsList.Count; i++)
                            {
                                if (data.FortsPositionsList[i].Account == item.Account)
                                {
                                    if (data.FortsPositionsList[i].CurrentEmptyPos != 0)
                                    {
                                        cfg.SetLog("Риск-менеджер. Счет: " +
                                            "-" + item.Account + "-" + item.ClientCode + ": " +
                                            "Фортс. Закрытие позиции перед вечермин клирингом" +
                                            //" Блокируемые средства: " + item.Block +
                                            " Средства: " + item.Deposite +
                                            " Текущие средства: " + item.CurrentBalance +
                                            " Операция: " + (data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B') +
                                            " Количество: " + (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos) +
                                            " Цена: " + data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S') +
                                            " Прибыль: " + item.Full +
                                            " Блокировка(Авто): " + rMItem.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                        mainWindow.Terminals.SendOrder
                                        (
                                            data.FortsPositionsList[i].Account,
                                            data.FortsPositionsList[i].Account,
                                            data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B',
                                            data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S'),
                                            (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos),
                                            data.FortsPositionsList[i].Seccode,
                                            data.GetClasscode(data.FortsPositionsList[i].Seccode)
                                        );
                                        result = false;
                                    }
                                }
                            }
                        }
                        #endregion
                    }
                    else
                    {
                        if (Settings.Default.IsWorkCPSession == true)
                        {
                            end = new DateTime
                            (
                                DateTime.Now.Year,
                                DateTime.Now.Month,
                                DateTime.Now.Day,
                                Settings.Default.StopSessionFortsHH,
                                Settings.Default.StopSessionFortsMM,
                                00
                            );
                            start = end.Subtract(TimeSpan.FromMinutes(Settings.Default.CPSessionValue));
                            #region close
                            if (DateTime.Now >= start && DateTime.Now < end)
                            {
                                // закрытие позиций
                                for (int i = 0; i < data.FortsPositionsList.Count; i++)
                                {
                                    if (data.FortsPositionsList[i].Account == item.Account)
                                    {
                                        if (data.FortsPositionsList[i].CurrentEmptyPos != 0)
                                        {
                                            cfg.SetLog("Риск-менеджер. Счет: " +
                                               item.Account + "-" + item.ClientCode + ": " +
                                               "Фортс. Закрытие позиции перед окончанием торгов" +
                                                //" Блокируемые средства: " + item.Block +
                                               " Средства: " + item.Deposite +
                                               " Текущие средства: " + item.CurrentBalance +
                                               " Операция: " + (data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B') +
                                               " Количество: " + (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos) +
                                               " Цена: " + data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S') +
                                               " Прибыль: " + item.Full +
                                               " Блокировка(Авто): " + rMItem.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");

                                            mainWindow.Terminals.SendOrder
                                            (
                                                data.FortsPositionsList[i].Account,
                                                data.FortsPositionsList[i].Account,
                                                data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'S' : 'B',
                                                data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, data.FortsPositionsList[i].CurrentEmptyPos > 0 ? 'B' : 'S'),
                                                (int)Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos),
                                                data.FortsPositionsList[i].Seccode,
                                                data.GetClasscode(data.FortsPositionsList[i].Seccode)
                                            );
                                            result = false;
                                        }
                                    }
                                }
                            }
                            #endregion
                        }
                    }

                    #endregion
                }
                else
                {
                    if (Settings.Default.IsWorkCPSession == true)
                    {
                        #region initialize timezone

                        DateTime end = new DateTime
                        (
                            DateTime.Now.Year,
                            DateTime.Now.Month,
                            DateTime.Now.Day,
                            Settings.Default.StopSessionHH,
                            Settings.Default.StopSessionMM,
                            00
                        );
                        DateTime start = end.Subtract(TimeSpan.FromMinutes(Settings.Default.CPSessionValue));

                        #endregion

                        if (DateTime.Now >= start && DateTime.Now < end)
                        {
                            // закрытие позиций
                            for (int i = 0; i < data.EmitentLimiteList.Count; i++)
                            {
                                if (data.EmitentLimiteList[i].Account == item.Account && data.EmitentLimiteList[i].ClientCode == item.ClientCode)
                                {
                                    if (data.EmitentLimiteList[i].Balance != 0)
                                    {
                                        cfg.SetLog(
                                               "Риск-менеджер. Счет: " +
                                               item.Account + "-" + item.ClientCode + ": " +
                                               "ММВБ. Закрытие позиции перед окончанием торгов" +
                                            //" Блокируемые средства: " + item.Block +
                                               " Средства: " + item.Deposite +
                                               " Текущие средства: " + item.CurrentBalance +
                                               " Операция: " + (data.EmitentLimiteList[i].Balance > 0 ? 'S' : 'B') +
                                               " Количество: " + Math.Abs(data.EmitentLimiteList[i].Balance) / data.GetLots(data.EmitentLimiteList[i].Seccode) +
                                               " Цена: " + "по рынку" +
                                               " Прибыль: " + item.Full +
                                               " Блокировка(Авто): " + rMItem.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                        mainWindow.Terminals.SendMMMarket
                                        (
                                            data.EmitentLimiteList[i].Account,
                                            data.EmitentLimiteList[i].ClientCode,
                                            data.EmitentLimiteList[i].Balance > 0 ? 'S' : 'B',
                                            Math.Abs(data.EmitentLimiteList[i].Balance) / data.GetLots(data.EmitentLimiteList[i].Seccode),
                                            data.EmitentLimiteList[i].Seccode,
                                            data.GetClasscode(data.EmitentLimiteList[i].Seccode)
                                        );

                                        result = false;
                                    }
                                }
                            }
                        }
                    }
                }
                _continueTime = true;
            }
            else
            {
                _continueTime = false;
                result = true;
            }
            result = true;
            return result;
        }

        /// <summary>
        /// Расчет комиссии
        /// </summary>
        /// <param name="rMItem"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public double GetComiss(RmItem rMItem, Data data)
        {
            try
            {
                // ммвб комиссия
                double result = 0;
                double volume = 0;
                for (int i = 0; i < data.DealList.Count; i++)
                {
                    if (data.DealList[i].Account == rMItem.Account &&
                            data.DealList[i].ClientCode == rMItem.ClientCode)
                    {
                        volume += data.DealList[i].Volume;
                    }
                }
                for (int i = 0; i < data.MmvbComisList.Count; i++)
                {
                    if (volume >= data.MmvbComisList[i].FromComis && volume < data.MmvbComisList[i].ToComis)
                    {
                        return data.MmvbComisList[i].Comis / 100;
                        break;
                    }
                    else
                    {
                        if (result == 0 && i == data.MmvbComisList.Count - 1)
                            return data.MmvbComisList[i].Comis / 100;
                    }
                }
                return 0;
            }
            catch
            {
                return 0;
            }
        }

        private bool _continue = false;

        /// <summary>
        /// Снятие и закрытий позиции при блокировке
        /// </summary>
        /// <returns></returns>
        private void CheckCancel(AccountLimiteItem item, RmItem rm)
        {
            if (_continue != true)
            {
                try
                {
                    if (item.Account == item.ClientCode)
                    {

                        #region снятие активных заявок


                        var activeO = data.GetOrderList(item.Account, item.ClientCode);
                        //activeO = data.GetOrderList(item.Account, item.ClientCode);
                        if (activeO.Count > 0)
                        {
                            bool result = false;

                            for (int i = 0; i < activeO.Count; i++)
                            {
                                //for (int j = 0; j < data.OrderBlockingItems.Count; j++)
                                //    if (activeO[i].Number == data.OrderBlockingItems[j].Number)
                                //        result = true;
                                if (result == false)
                                {
                                    cfg.SetLog(
                                            "Риск-менеджер. Счет: " +
                                            item.Account + "-" + item.ClientCode + ": " +
                                            "||||ФОРТС. Снятие заявок активных заявок||||" +
                                        //" Блокируемые средства: " + item.Block +
                                            " Средства: " + item.Deposite +
                                            " Текущие средства: " + item.CurrentBalance +
                                            " Прибыль: " + item.Full +
                                            " Номер заявки: " + activeO[i].Number +
                                            " Счет в заявке: " + activeO[i].ClientCode +
                                            " Блокировка(Авто): " + rm.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                    CancelOrder(activeO[i], activeO[i].Seccode, data.GetClasscode(activeO[i].Seccode));
                                    _continue = true;
                                }
                            }
                        }

                        #endregion

                        #region  снятие активных стоп-заявок

                        var activeS = data.GetStopOrderList(item.Account, item.ClientCode);
                        if (activeS.Count > 0)
                        {
                            for (int j = 0; j < activeS.Count; j++)
                            {
                                cfg.SetLog(
                                    "Риск-менеджер. Счет: " +
                                    item.Account + "-" + item.ClientCode + ": " +
                                    "ФОРТС. Снятие активных стоп заявок" +
                                    //" Блокируемые средства: " + item.Block +
                                    " Средства: " + item.Deposite +
                                    " Текущие средства: " + item.CurrentBalance +
                                    " Прибыль: " + item.Full +
                                    " Блокировка(Авто): " + rm.IsBlock +
                                    " Стоп-заявка №: " + activeS[j].Number +
                                    " Счет в стоп-заявке: " + activeS[j].ClientCode, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                CancelStopOrder(activeS[j], activeS[j].Seccode, data.GetClasscode(activeS[j].Seccode));

                                _continue = true;
                                //return false;
                            }
                        }
                        #endregion

                        #region закрытие по рынку

                        for (int i = 0; i < data.FortsPositionsList.Count; i++)
                        {
                            if (data.FortsPositionsList[i].Account == item.Account)
                            {
                                char operation = '\0';

                                if (data.FortsPositionsList[i].CurrentEmptyPos > 0) operation = 'S';
                                if (data.FortsPositionsList[i].CurrentEmptyPos < 0) operation = 'B';

                                if (operation != '\0')
                                {
                                    cfg.SetLog(
                                             "Риск-менеджер. Счет: " +
                                             item.Account + "-" + item.ClientCode + ": " +
                                             "ФОРТС. Закрытие позиций" +
                                        //" Блокируемые средства: " + item.Block +
                                             " Средства: " + item.Deposite +
                                             " Текущие средства: " + item.CurrentBalance +
                                             " Операция: " + operation +
                                             " Количество контрактов: " + Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos) / data.GetLots(data.FortsPositionsList[i].Seccode) +
                                             " Цена: " + "По рынку" +
                                             " Прибыль: " + item.Full +
                                             " Блокировка(Авто): " + rm.IsBlock, mainWindow.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod(), "");
                                    mainWindow.Terminals.SendOrder
                                    (
                                        data.FortsPositionsList[i].Account,
                                        data.FortsPositionsList[i].Account,
                                        operation,
                                        data.GetMaxMinPrice(data.FortsPositionsList[i].Seccode, operation == 'S' ? 'B' : 'S'),
                                        Math.Abs(data.FortsPositionsList[i].CurrentEmptyPos),
                                        data.FortsPositionsList[i].Seccode,
                                        data.GetClasscode(data.FortsPositionsList[i].Seccode)
                                    );
                                    data.FortsPositionsList[i].CurrentEmptyPos = 0;
                                    _continue = true;
                                }
                            }

                        }
                        #endregion

                    }
                    else
                    {
                        //double dostupno = data.GetDostupnoBalance(item);

                        //if (item.Block >= dostupno * (data.GetLaverage(item.ClientCode)) &&
                        //     dostupno != 0)
                        //{
                        //if (_continue == false)
                        //{
                        #region закрытие по рынку

                        for (int i = 0; i < data.EmitentLimiteList.Count; i++)
                        {
                            if (data.EmitentLimiteList[i].Account == item.Account && data.EmitentLimiteList[i].ClientCode == item.ClientCode)
                            {
                                char operation = '\0';

                                if (data.EmitentLimiteList[i].Balance > 0) operation = 'S';
                                if (data.EmitentLimiteList[i].Balance < 0) operation = 'B';

                                if (operation != '\0')
                                {
                                    cfg.SetLog("Риск-менеджер. Счет: " +
                                              item.Account + "-" + item.ClientCode + ": " +
                                             "ММВБ. Закрытие позиции." +
                                             " Средства: " + item.Deposite +
                                             " Текущие средства: " + item.CurrentBalance +
                                             " Прибыль: " + item.Full +
                                             " Блокировка(Авто): " + rm.IsBlock, mainWindow.ListBox_Logs);
                                    mainWindow.Terminals.SendMMMarket
                                    (
                                        data.EmitentLimiteList[i].Account,
                                        data.EmitentLimiteList[i].ClientCode,
                                        operation,
                                        Math.Abs(data.EmitentLimiteList[i].Balance) / data.GetLots(data.EmitentLimiteList[i].Seccode),
                                        data.EmitentLimiteList[i].Seccode,
                                        data.GetClasscode(data.EmitentLimiteList[i].Seccode)
                                    );
                                }
                            }
                        }

                        #endregion

                        #region  снятие активных стоп-заявок

                        var activeS = data.StopOrderList.Where(a => a.TradeAccount == item.Account && a.ClientCode == item.ClientCode && a.Status == cfg.Active).ToList();
                        if (activeS.Count > 0)
                        {
                            for (int j = 0; j < activeS.Count; j++)
                            {

                                cfg.SetLog("Риск-менеджер. Счет: " + item.Account + "-" + item.ClientCode + ": " +
                                    "ММВБ. Снятие стоп заявок." +
                                    //" Блокируемые средства: " + item.Block +
                                    " Средства: " + item.Deposite +
                                    " Текущие средства: " + item.CurrentBalance +
                                    " Прибыль: " + item.Full +
                                    " Блокировка(Авто): " + rm.IsBlock, mainWindow.ListBox_Logs);
                                CancelStopOrder(activeS[j], activeS[j].Seccode, data.GetClasscode(activeS[j].Seccode));
                            }
                        }
                        #endregion

                        #region снятие активных заявок

                        var activeO = data.OrderList.Where(a => a.Account == item.Account && a.ClientCode == item.ClientCode && a.Status == cfg.Active).ToList();
                        if (activeO.Count > 0)
                        {
                            for (int i = 0; i < activeO.Count; i++)
                            {
                                cfg.SetLog("Риск-менеджер. Счет: " + item.Account + "-" + item.ClientCode + ": " +
                                        "ММВБ.|Снятие заявок." +
                                    //" Блокируемые средства: " + item.Block +
                                        " Средства: " + item.Deposite +
                                        " Текущие средства: " + item.CurrentBalance +
                                        " Прибыль: " + item.Full +
                                        " Блокировка(Авто): " + rm.IsBlock, mainWindow.ListBox_Logs);
                                CancelOrder(activeO[i], activeO[i].Seccode, data.GetClasscode(activeO[i].Seccode));
                            }
                        }

                        #endregion
                    }
                    //}
                    //}
                }
                catch (Exception ex)
                {
                    cfg.SetLog(ex.Message, MainWindow.StaticRiskMan.ListBox_Logs, GetType(), MethodBase.GetCurrentMethod());
                }
            }


        }

        private double GetPlanPos(ObservableCollection<LimitByAccountModel> observableCollection, AccountLimiteItem ac)
        {
            for (int i = 0; i < observableCollection.Count; i++)
            {
                if (observableCollection[i].Account == ac.Account && observableCollection[i].TypeLimit != cfg.ZalogMoney)
                    return observableCollection[i].PlanEmptyPosition;
            }

            return 0;
        }


        private TimeSpan timeMessageReapeat = new TimeSpan(0, 1, 0);
        private static DateTime LastTimeMessage = DateTime.Now;
        private void IsParam()
        {
            try
            {
                if (data.CurrentList.Count != 0)
                {

                }
                else
                {
                    if (LastTimeMessage.TimeOfDay < DateTime.Now.TimeOfDay + timeMessageReapeat)
                    {
                        LastTimeMessage = DateTime.Now;
                        try
                        {
                            QuikUtil.StopDDE();
                            data.Clear();
                            QuikUtil.StartDDE();
                        }
                        catch (Exception ex)
                        {
                            new DialogOkCancel(ex.ToString(), "Данные по ДДЕ из таблицы текущих параметров не поступают в РМ");
                        }
                    }
                }
            }
            catch (Exception) { }

        }



        public double GetLimitOpenPos(AccountLimiteItem item)
        {
            if (item.Account == item.ClientCode)
            {
                var ac = data.LimitebyAccount.Where(a => a.Account == item.Account).ToList();

                for (int i = 0; i < ac.Count; i++)
                {
                    if (ac[i].LimitOpenPosition == 0)
                    {
                        for (int j = 0; j < data.Portfel.Count; j++)
                        {
                            if (data.Portfel[j].SrochAccount == item.ClientCode)
                            {
                                return data.Portfel[j].EnterSredstva;
                            }
                        }
                    }
                    else
                        return ac[i].LimitOpenPosition;
                }
            }
            else
            {
                for (int i = 0; i < data.Portfel.Count; i++)
                {
                    if (data.Portfel[i].CodeClient == item.ClientCode)
                    {
                        return data.Portfel[i].EnterSredstva;
                    }
                }
            }

            return 0;
        }
        /// <summary>
        /// Вычисление текущего состояния счета
        /// </summary>
        /// <param name="account">торговый счет</param>
        /// <returns>Возвращает текущий баланс</returns>
        private double GetBalance(RmItem item)
        {
            if (item.Account == item.ClientCode)
            {
                var ac = data.LimitebyAccount.Where(a => a.Account == item.Account).ToList();
                double _d = GetB(item);
                if (_d == 0)
                {
                    if (item.TypeEnterLimite == "Обычный")
                    {
                        for (int i = 0; i < ac.Count; i++)
                            return ac[i].LimitOpenPosition;
                    }
                    if (item.TypeEnterLimite == "Трейлинг профит" || item.TypeEnterLimite == cfg.TypeEnterLimitRmDealTrallingProfit)
                    {
                        for (int i = 0; i < ac.Count; i++)
                            return ac[i].LimitOpenPosition + ac[i].VariableMarga + ac[i].Dohod;
                    }
                }
                else
                {
                    if (item.TypeEnterLimite == "Обычный")
                    {
                        for (int i = 0; i < ac.Count; i++)
                            return _d;
                    }
                    if (item.TypeEnterLimite == "Трейлинг профит" || item.TypeEnterLimite == cfg.TypeEnterLimitRmDealTrallingProfit)
                    {
                        for (int i = 0; i < ac.Count; i++)
                            return _d + ac[i].VariableMarga + ac[i].Dohod;
                    }
                }
            }
            else
            {
                if (item.TypeEnterLimite == "Обычный")
                {
                    for (int i = 0; i < data.Portfel.Count; i++)
                    {
                        if (data.Portfel[i].CodeClient == item.ClientCode)
                            return data.Portfel[i].EnterSredstva;
                    }
                }
                if (item.TypeEnterLimite == "Трейлинг профит" || item.TypeEnterLimite == cfg.TypeEnterLimitRmDealTrallingProfit)
                {
                    for (int i = 0; i < data.Portfel.Count; i++)
                    {
                        if (data.Portfel[i].CodeClient == item.ClientCode)
                            return data.Portfel[i].EnterSredstva + data.Portfel[i].ProfitLoss;
                    }
                }
            }

            return 0;
        }

        private double GetB(RmItem item)
        {
            var ac = data.Portfel.Where(a => a.SrochAccount == item.Account).ToList();

            for (int i = 0; i < ac.Count; i++)
                return ac[i].EnterSredstva;

            return 0;
        }



        /// <summary>
        /// проверка по транзакциям на изменения статуса
        /// </summary>
        private string ChangeStatusOrder(int ID, string _Account, string _ClientCode)
        {
            string result = "unknown";
            foreach (var item in mainWindow._dataProvider.GetOrderListAll(_Account, _ClientCode))
                if (item.Tid == ID)
                {
                    result = item.Status;
                    //CFG.SetLog("Изменение статуса заявки " + type + ": " + item.Status + " № заявки: " + item.Number +" Уровень: " +item.Price  ,mainWindow.ListBox_Logs);
                }
            return result;
        }

        public bool IsList(AccountLimiteItem item)
        {
            bool tr = false;
            for (int i = 0; i < data.ACLimiteItems.Count; i++)
                if (data.ACLimiteItems[i].ClientCode == item.ClientCode)
                    tr = true;
            return tr;
        }
        private void GetList(AccountLimiteItem item)
        {
            for (int i = 0; i < data.ACLimiteItems.Count; i++)
            {
                if (data.ACLimiteItems[i].ClientCode == item.ClientCode)
                    item = data.ACLimiteItems[i];
            }
        }

        private void UpdateList(AccountLimiteItem item)
        {
            bool tr = false;
            for (int i = 0; i < data.ACLimiteItems.Count; i++)
            {
                if (data.ACLimiteItems[i].ClientCode == item.ClientCode && data.ACLimiteItems[i].Account == item.Account)
                {
                    tr = true;
                    data.ACLimiteItems[i] = item;
                }
            }
            if (tr == false)
                data.ACLimiteItems.Add(item);
        }

        private AccountLimiteItem GetRow(AccountLimiteItem item)
        {
            for (int i = 0; i < data.ACLimiteItems.Count; i++)
            {
                if (data.ACLimiteItems[i].ClientCode == item.ClientCode)
                {
                    item.Deposite = data.ACLimiteItems[i].Deposite;
                    return item;
                }
            }
            return null;
        }

        #region функции для отправки транзакций в квики

        public void SendOrder(char operation, double price, int lot, string seccode, string classcode, string account, string clientcode)
        {
            int i = 0;
            int tid = 0;
            foreach (var tmp in mainWindow._dataProvider.T2QItems)
            {

                foreach (var t in tmp.TradeList)
                {
                    if (t.Account == account && t.ClientCode == clientcode.Substring(0, clientcode.IndexOf('/')))
                    {
                        if (i == 0)
                            tid = mainWindow.Terminals.TransQuikItems_0.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 1)
                            tid = mainWindow.Terminals.TransQuikItems_1.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 2)
                            tid = mainWindow.Terminals.TransQuikItems_2.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 3)
                            tid = mainWindow.Terminals.TransQuikItems_3.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 4)
                            tid = mainWindow.Terminals.TransQuikItems_4.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 5)
                            tid = mainWindow.Terminals.TransQuikItems_5.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 6)
                            tid = mainWindow.Terminals.TransQuikItems_6.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 7)
                            tid = mainWindow.Terminals.TransQuikItems_7.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 8)
                            tid = mainWindow.Terminals.TransQuikItems_8.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                        if (i == 9)
                            tid = mainWindow.Terminals.TransQuikItems_9.SendOrder(operation, price, lot, seccode, classcode, account, clientcode);
                    }
                }
                i++;
            }

            //string r = "";
            //if (operation == 'S')
            //    r = cfg.Sell;
            //else
            //    r = cfg.Buy;

            //data.OrderBlockingItems.Add(new OrderModel()
            //{
            //    TID = tid,
            //    Seccode = seccode,
            //    Operation = r,
            //    Account = account,
            //    ClientCode = (clientcode.Split('/'))[0],
            //    Count = lot
            //});
        }

        private void CancelStopOrder(StopOrderModel orderModel, string seccode, string classcode)
        {
            int i = 0;
            foreach (var tmp in mainWindow._dataProvider.T2QItems)
            {
                foreach (var t in tmp.TradeList)
                {
                    if (t.Account == orderModel.TradeAccount && t.ClientCode == orderModel.ClientCode)
                    {
                        if (i == 0)
                            mainWindow.Terminals.TransQuikItems_0.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 1)
                            mainWindow.Terminals.TransQuikItems_1.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 2)
                            mainWindow.Terminals.TransQuikItems_2.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 3)
                            mainWindow.Terminals.TransQuikItems_3.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 4)
                            mainWindow.Terminals.TransQuikItems_4.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 5)
                            mainWindow.Terminals.TransQuikItems_5.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 6)
                            mainWindow.Terminals.TransQuikItems_6.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 7)
                            mainWindow.Terminals.TransQuikItems_7.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 8)
                            mainWindow.Terminals.TransQuikItems_8.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                        if (i == 9)
                            mainWindow.Terminals.TransQuikItems_9.CancelStopOrder(orderModel.Number, seccode, classcode, orderModel.TradeAccount, orderModel.ClientCode);
                    }
                }
                i++;
            }
        }

        private void CancelOrder(OrderModel orderModel, string seccode, string classcode)
        {
            int i = 0;
            foreach (var tmp in mainWindow._dataProvider.T2QItems)
            {
                foreach (var t in tmp.TradeList)
                {
                    if (t.Account == orderModel.Account && t.ClientCode == orderModel.ClientCode)
                    {
                        if (i == 0)
                            mainWindow.Terminals.TransQuikItems_0.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 1)
                            mainWindow.Terminals.TransQuikItems_1.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 2)
                            mainWindow.Terminals.TransQuikItems_2.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 3)
                            mainWindow.Terminals.TransQuikItems_3.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 4)
                            mainWindow.Terminals.TransQuikItems_4.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 5)
                            mainWindow.Terminals.TransQuikItems_5.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 6)
                            mainWindow.Terminals.TransQuikItems_6.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 7)
                            mainWindow.Terminals.TransQuikItems_7.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 8)
                            mainWindow.Terminals.TransQuikItems_8.CancelOrder(orderModel.Number, seccode, classcode);
                        if (i == 9)
                            mainWindow.Terminals.TransQuikItems_9.CancelOrder(orderModel.Number, seccode, classcode);
                    }
                }
                i++;
            }
        }

        private void CloseMarket(PositionToClientAccountModel positionToClientAccountModel, AccountLimiteItem item, int lot)
        {
            char op = 'r';
            char o = 'r';
            if (positionToClientAccountModel.CurrentEmptyPos > 0)
            {
                o = 'S';
                op = 'B';
            }
            if (positionToClientAccountModel.CurrentEmptyPos < 0)
            {
                o = 'B';
                op = 'S';
            }

            int i = 0;
            foreach (var tmp in mainWindow._dataProvider.T2QItems)
            {

                foreach (var t in tmp.TradeList)
                {
                    if (t.Account == item.Account && t.ClientCode == item.ClientCode)
                    {
                        if (i == 0)
                            mainWindow.Terminals.TransQuikItems_0.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 1)
                            mainWindow.Terminals.TransQuikItems_1.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 2)
                            mainWindow.Terminals.TransQuikItems_2.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 3)
                            mainWindow.Terminals.TransQuikItems_3.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 4)
                            mainWindow.Terminals.TransQuikItems_4.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 5)
                            mainWindow.Terminals.TransQuikItems_5.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 6)
                            mainWindow.Terminals.TransQuikItems_6.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 7)
                            mainWindow.Terminals.TransQuikItems_7.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 8)
                            mainWindow.Terminals.TransQuikItems_8.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                        if (i == 9)
                            mainWindow.Terminals.TransQuikItems_9.Market(o,
                                data.GetMaxMinPrice(positionToClientAccountModel.Seccode, op),
                                data.GetClasscode(positionToClientAccountModel.Seccode),
                                positionToClientAccountModel.Seccode,
                                Math.Abs(lot),
                                item.Account,
                                item.ClientCode + "//RiskMan");
                    }
                }
                i++;
            }
        }

        #endregion
    }
}
